package com.vmj.rtda;

import com.vmj.heap.VMObject;
/**
 * Created by yangshoujun on 2017/8/12 下午12:02.
 */
public class OperandStack {
    int size;
    Slot[] slots;

    public OperandStack(int size) {
        slots = new Slot[size];
    }

    public void pushInt(int value) {
        Slot slot = new Slot();
        slot.setNum(value);
        slots[size++] = slot;
    }

    public int popInt() {
        Slot slot = slots[--size];
        slots[size] = null;
        return slot.getNum();
    }

    public void pushFloat(float value) {
        Slot slot = new Slot();
        int val = Float.floatToIntBits(value);
        slot.setNum(val);
        slots[size++] = slot;
    }

    public float popFloat() {
        int val = slots[--size].getNum();
        slots[size] = null;
        return Float.intBitsToFloat(val);
    }

    public void pushLong(long value) {
        int i1 = (int)value;
        int i2 = (int)(value >> 32);

        Slot slot1 = new Slot();
        slot1.setNum(i1);
        slots[size++] = slot1;

        Slot slot2 = new Slot();
        slot2.setNum(i2);
        slots[size++] = slot2;
    }

    public long popLong() {
        int i2 = popInt();
        int i1 = popInt();

        long l1 = (long)((i2 & 0x000000ffffffffL) << 32);
        long l2 = i1 & 0x00000000ffffffffL;
        return l1 | l2;
    }

    public void pushDouble(double value) {
        long l = Double.doubleToLongBits(value);
        pushLong(l);
    }

    public double popDouble() {
        long l = popLong();
        double d = Double.longBitsToDouble(l);
        return d;
    }

    public void pushRef(java.lang.Object object) {
        Slot slot = new Slot();
        slot.setRef(object);
        slots[size++] = slot;
    }

    public VMObject popRef() {
        Slot slot = slots[--size];
        VMObject ref = (VMObject) slot.ref;
        slots[size] = null;
        return ref;
    }

    public void pushBoolean(boolean val) {
        if(val) {
            pushInt(1);
        } else {
            pushInt(0);
        }
    }

    public void clear() {
        for(Slot slot : slots) {
            slot = null;
        }
    }

    public VMObject getRefFromTop(int n) {
        return (VMObject) slots[size - 1 - n].ref;
    }

    public void pushSlot(Slot slot) {
        slots[size++] = slot;
    }

    public Slot popSlot() {
        return slots[--size];
    }

    public int getSize() {
        return size;
    }

    public Slot[] getSlots() {
        return slots;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public void setSlots(Slot[] slots) {
        this.slots = slots;
    }
}
